% this is used to calculate best feedback resistor combination for minimum error of DCDC circuit
% 用于计算DCDC电路反馈电阻的最优组合方式，以达到最小输出误差

% table of resistor value, which are easy to by
% unit: Kohm
basic_r = [1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, ...
           2.0, 2.2, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, ...
           4.3, 4.7, 4.99, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1];
all_r = [basic_r, basic_r*10, basic_r*100];

% change your target voltage here
target_voltage = 5.3;
% change your feedback voltage here
fb_voltage = 0.61255; % 0.61255   0.6

calc_result = [0, 0, 0]; % r_small, r_big, actual_volatge
% just find in basic table, this is enough
for i=1:length(basic_r)
    r_small = basic_r(i);
    % calculate ideal target value
    target_r = basic_r(i) * target_voltage / fb_voltage - basic_r(i);
    %fprintf("r_small:%f target_r:%f\r\n", r_small, target_r);
    % find ideal target value
    for j=1:length(all_r)
        if (all_r(j) <= target_r && all_r(j+1) >= target_r)
            % FIXME: j+1 may overflow when target_r big enough
            %fprintf("target_r:%f j:%d l:%f r:%f\r\n", target_r, j, all_r(j), all_r(j+1));
            break
        end
    end
    actual_volatge_a = fb_voltage * (basic_r(i) + all_r(j)) / basic_r(i);
    actual_volatge_b = fb_voltage * (basic_r(i) + all_r(j+1)) / basic_r(i);

    % get best choice of this basic_r(i)
    %fprintf("v_a:%f v_b:%f\r\n", actual_volatge_a, actual_volatge_b);
    if(abs(actual_volatge_a- target_voltage) < abs(actual_volatge_b- target_voltage))
        actual_volatge = actual_volatge_a;
        r_big = all_r(j);
    else
        actual_volatge = actual_volatge_b;
        r_big = all_r(j+1);
    end
    calc_result = [calc_result; [r_small, r_big, actual_volatge]];
end

% if need error to be >=0 or <=0, change this line
error = abs(calc_result(:, 3) - target_voltage);
% get best choice of target voltage
[min_error, pos] = min(error);

% print best choice
fprintf("cal result:\n");
fprintf("r_small:%fK r_big:%fK actual_volatge:%fV error:%fV\n", ...
    calc_result(pos, 1), calc_result(pos,2), calc_result(pos,3), ...
    error(pos));
